package com.diligent.cloud.sfc.service.impl;


import com.canny.commons.model.ObjectResult;
import com.canny.commons.page.IPage;
import com.canny.commons.page.Pagination;
import com.diligent.cloud.logistics.container.model.LcmTransport;
import com.diligent.cloud.logistics.container.model.LcmTransportMaster;
import com.diligent.cloud.logistics.container.model.LcmTransportMat;
import com.diligent.cloud.logistics.container.service.LcmTransportMasterFeignService;
import com.diligent.cloud.logistics.container.service.LcmTransportMatFeignService;
import com.diligent.cloud.primary.data.model.Result;
import com.diligent.cloud.primary.data.model.rt.RtWorkCenter;
import com.diligent.cloud.sfc.model.params.ConsumablesOutOfWarehouseParams;
import com.diligent.cloud.sfc.model.params.FinishedGoodsOutOfWarehouseParams;
import com.diligent.cloud.sfc.service.ISfcService;
import com.diligent.cloud.sfc.service.WipService;
import com.diligent.cloud.web.model.PageAndCondition;
import com.diligent.cloud.wip.core.feign.service.WipStorageFeginService;
import com.diligent.cloud.wip.core.feign.service.WipStorageLedgerFeignService;
import com.diligent.cloud.wip.core.vo.ConsumeOut;
import com.diligent.cloud.wip.core.vo.GuideMaster;
import com.diligent.cloud.wip.core.vo.StorageLedgerInfo;
import com.diligent.cloud.wip.panel.feign.service.WipStorageBinFeignService;
import com.diligent.cloud.wip.panel.modle.WipStorageBin;
import com.diligent.cloud.wip.panel.modle.WipStorageLedger;
import com.diligent.foundation.data.model.v2.Condition;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;

import java.security.Principal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;

/**
 * WipServiceImpl class
 *
 * @author xf107278
 * @date 4/7/2020
 */
@Service
public class WipServiceImpl implements WipService {


    private WipStorageLedgerFeignService wipStorageLedgerFeignService;

    private WipStorageFeginService wipStorageFeginService;

    private ISfcService sfcService;

    private final WipStorageBinFeignService wipStorageBinFeignService;

    private final LcmTransportMasterFeignService lcmTransportMasterFeignService;

    private final LcmTransportMatFeignService lcmTransportMatFeignService;

    public WipServiceImpl(
                          WipStorageLedgerFeignService wipStorageLedgerFeignService,
                          WipStorageFeginService wipStorageFeginService, ISfcService sfcService,
                          WipStorageBinFeignService wipStorageBinFeignService,
                          LcmTransportMasterFeignService lcmTransportMasterFeignService,
                          LcmTransportMatFeignService lcmTransportMatFeignService) {
        this.wipStorageLedgerFeignService = wipStorageLedgerFeignService;
        this.wipStorageFeginService = wipStorageFeginService;
        this.sfcService = sfcService;
        this.wipStorageBinFeignService = wipStorageBinFeignService;
        this.lcmTransportMasterFeignService = lcmTransportMasterFeignService;
        this.lcmTransportMatFeignService = lcmTransportMatFeignService;
    }

    @Override
    public ResponseEntity<ObjectResult> getInventoryByMatCodeAndCwocCode(String matCode, String cwocCode,
                                                                         String batchCode, Long systemId) {
        RtWorkCenter workCenter = sfcService.getWorkCenterByCwocCode(cwocCode);

        ObjectResult<WipStorageLedger> ledgerByStorageAndMat =
                wipStorageLedgerFeignService.getLedger(workCenter.getStorageCode(), matCode,
                        batchCode, systemId);

        return ResponseEntity.ok(ledgerByStorageAndMat);

    }

    @Override
    public ResponseEntity<ObjectResult> addMatStorage(GuideMaster guideMaster, Principal principal) {
        ObjectResult warehouse = wipStorageFeginService.warehouse(guideMaster);
        return ResponseEntity.ok(warehouse);
    }


    @Override
    public ResponseEntity<ObjectResult> updateMatStorage(FinishedGoodsOutOfWarehouseParams finishedGoodsWarehouseParams) {
        GuideMaster guideMaster = finishedGoodsWarehouseParams.getGuideMaster();

        return ResponseEntity.ok(wipStorageFeginService.undercarriage(guideMaster));
    }

    @Override
    public ResponseEntity<ObjectResult> updateConsumeStorage(ConsumablesOutOfWarehouseParams consumeOutOfStorageParams) {
        ConsumeOut consumeOut = consumeOutOfStorageParams.getConsumeOut();
        return ResponseEntity.ok(wipStorageFeginService.consumeOut(consumeOut));
    }

    @Override
    public ResponseEntity<ObjectResult> getInventoryByMatCodeAndCwocCodes(String cwocCode, Long systemId,
                                                                          List<StorageLedgerInfo> sameList) {
        RtWorkCenter rtWorkCenter = sfcService.getWorkCenterByCwocCode(cwocCode);
        ObjectResult<WipStorageLedger> collectLedger =
                wipStorageLedgerFeignService.getCollectLedger(systemId,
                        rtWorkCenter.getStorageCode(), new ArrayList(new HashSet<>(sameList)));
        return ResponseEntity.ok(collectLedger);
    }

    @Override
    public ResponseEntity<ObjectResult> addWipStorageBin(WipStorageBin wipStorageBin, Principal principal) {
        wipStorageBin.setEnterCode(principal.getName());
        wipStorageBin.setEnterName(principal.getName());
        wipStorageBin.setEnterTime(LocalDateTime.now());
        ObjectResult<WipStorageBin> save = wipStorageBinFeignService.save(wipStorageBin);
        return ResponseEntity.ok(save);
    }

    @Override
    public ResponseEntity<ObjectResult> getTransportingMatInventory(String matCode, String cwocCode, String batchCode,
                                                                    Long systemId) {
        RtWorkCenter rtWorkCenter = sfcService.getWorkCenterByCwocCode(cwocCode);
        PageAndCondition pageAndCondition = new PageAndCondition();
        List<Condition> conditions = new ArrayList<>();
        pageAndCondition.setPagination(new Pagination(1L, 100000L));
        conditions.add(new Condition("isCanceled", "eq", 0, null));
        conditions.add(new Condition("isFinished", "eq", 0, null));
        conditions.add(new Condition("isClosed", "eq", 0, null));
        conditions.add(new Condition("storageCode2", "eq", rtWorkCenter.getStorageCode(), null));
        conditions.add(new Condition("companyCode2", "eq", rtWorkCenter.getPlantCode(), null));
        conditions.add(new Condition("cwocCode2", "eq", rtWorkCenter.getCwocCode(), null));
        conditions.add(new Condition("systemId", "eq", systemId, null));


        List<LcmTransport> lcmTransports = new ArrayList<>();
        //查找到运输到此车间的未完成运输单
        ResponseEntity<Result<IPage<LcmTransportMaster>>> lcmTransportMasterPage =
                lcmTransportMasterFeignService.page(pageAndCondition);
        //循环查找符合条件的运输单
        if (lcmTransportMasterPage.getBody()==null){return ResponseEntity.ok(new ObjectResult());}
        for (LcmTransportMaster transportMaster : lcmTransportMasterPage.getBody().getData().getRecords()) {
            conditions = new ArrayList<>();
            conditions.add(new Condition("masterId", "eq", transportMaster.getId(), null));
            conditions.add(new Condition("matCode", "eq", matCode, null));
            conditions.add(new Condition("batchCode", "eq", batchCode, null));

            pageAndCondition.setConditions(conditions);
            ResponseEntity<Result<IPage<LcmTransportMat>>> lcmTransportMatPage =
                    lcmTransportMatFeignService.page(pageAndCondition);
            //寻找到符合的运输物料单
            List<LcmTransportMat> lcmTransportMats = new ArrayList<>();
            if (lcmTransportMatPage.getBody()==null){continue;}
            for (LcmTransportMat transportMat : lcmTransportMatPage.getBody().getData().getRecords()) {

                lcmTransportMats.add(transportMat);
            }
            if (lcmTransportMats.size() != 0) {
                LcmTransport lcmTransport = new LcmTransport();
                lcmTransport.setLcmTransportMaster(transportMaster);
                lcmTransport.setLcmTransportMat(lcmTransportMats);
                lcmTransports.add(lcmTransport);
            }

        }

        return ResponseEntity.ok(new ObjectResult(lcmTransports));
    }

}
